using System;
using System.Collections.Generic;
using System.Text;
using Game.Framework.Utils;
using TMPro;
using UnityEngine;

namespace Game.Framework.Localization
{
    
    public static class Locale
    {
        public const string NONE = "none";
        public const string ENGLISH = "en";
        public const string FRENCH = "fr";
        public const string GERMAN = "de";
        public const string PORTUGUESE = "pt";
        public const string JAPANESE = "jp";
        public const string KOREA = "kr";
        public const string CHINESE_SIMPLIFIED = "zh";
        public const string CHINESE_TRADITION = "zht";
        public const string SPANISH = "es";
        public const string ITALIAN = "it";
        public const string INDONESIAN = "id";
        public const string RUSSIAN = "ru";
        public const string VIETNAMESE = "vi";
        public const string TURKISH = "tr";
        public const string THAI = "th";
        public const string HINDI = "hi";
        public const string Dutch = "nl";// 荷兰
    }
    
    public class LocalizationManager : Singleton<LocalizationManager>
    {
        
        private string m_current_locale = Locale.ENGLISH;
        
        private Dictionary<string, Material> m_CacheMaterial = new Dictionary<string, Material>();
        private Dictionary<string, TMP_FontAsset> m_CacheFont = new Dictionary<string, TMP_FontAsset>();
        
//         // 配置已经支持的语言
//         public readonly List<string> SupportedLocale = new List<string> {
//             Locale.ENGLISH,
//             Locale.GERMAN,
//             Locale.FRENCH,
//             Locale.KOREA,
//             Locale.JAPANESE,
//             Locale.SPANISH,
//             Locale.PORTUGUESE,
//             Locale.CHINESE_TRADITION,
//             Locale.ITALIAN,
//             Locale.THAI,
//             Locale.INDONESIAN,
//             Locale.VIETNAMESE,
// #if DEBUG || DEVELOPMENT_BUILD
//             Locale.CHINESE_SIMPLIFIED,
// #endif
//             // Locale.RUSSIAN,
//         };

        public readonly List<string> SupportedLocale = new List<string> {
            Locale.ENGLISH,
#if DEBUG || DEVELOPMENT_BUILD
            Locale.CHINESE_SIMPLIFIED,
#endif
            // Locale.RUSSIAN,
        };
        
        private static readonly StringBuilder m_builder = new StringBuilder();
        private static readonly object m_lock = new object(); // thread safe
        
        private static string Format(string s, params object[] values)
        {
            if (string.IsNullOrEmpty(s)) return string.Empty;
            if (values.Length < 1) return s; // params is empty

            int vi = 0, start = 0, now = 0, len = s.Length; // value index, current start position, current search position

            lock (m_lock)
            {
                m_builder.Clear();
                while (now < len)
                {
                    if (s[now++] != '%') continue;
                    var c = s[now++];
                    if (c == 's' || c == 'S')
                    {
                        var v = values[vi++];
                        m_builder.Append(s.Substring(start, now - start - 2)).Append(v == null ? string.Empty : v.ToString());
                        start = now;

                        if (vi >= values.Length) break;
                    }
                }
                if (start < len) m_builder.Append(s.Substring(start));

                return m_builder.ToString();
            }
        }


//         public void MatchLanguage()
//         {
//             StorageGlobal storage = StorageManager.Instance.GetStorage<StorageGlobal>();
//             if (string.IsNullOrEmpty(storage.Locale))
//             {
//                 string userLanguage = GetSystemLanguage();
//                 storage.Locale = userLanguage;
//                 storage.OrigLocale = userLanguage;
//                 SetCurrentLocale(userLanguage);
//             }
//             else
//             {
// #if DEBUG || DEVELOPMENT_BUILD
//                 storage.Locale = "en";
// #endif
//                 if (SupportedLocale.Contains(storage.Locale))
//                 {
//                     SetCurrentLocale(storage.Locale);
//                 }
//                 else
//                 {
//                     string userLanguage = GetSystemLanguage();
//                     storage.Locale = userLanguage;
//                     storage.OrigLocale = userLanguage;
//                     SetCurrentLocale(userLanguage);
//                 }
//             }
//         }

        /// <summary>
        /// 设置本地化语言
        /// </summary>
        /// <param name="locale"></param>
        /// <returns></returns>
        public bool SetCurrentLocale(string locale)
        {
            if (string.IsNullOrEmpty(locale))
            {
                return false;
            }

            if (m_current_locale == locale)
            {
                return false;
            }

            if (!SupportedLocale.Contains(locale))
            {
                return false;
            }

            m_current_locale = locale;
            return true;
        }
        
        private string GetSystemLanguage()
        {
            var systemLanguage = Application.systemLanguage;
            string osLanguage = GetSystemLanguage(systemLanguage);
            return GetLocal(osLanguage);
        }

        private string GetSystemLanguage(SystemLanguage language)
        {
            switch (language)
            {
                case SystemLanguage.Afrikaans: return "af";
                case SystemLanguage.Arabic: return "ar";
                case SystemLanguage.Basque: return "eu";
                case SystemLanguage.Belarusian: return "be";
                case SystemLanguage.Bulgarian: return "bg";
                case SystemLanguage.Catalan: return "ca";
                case SystemLanguage.Chinese: return "zh";
                case SystemLanguage.ChineseSimplified: return "zh";
                case SystemLanguage.ChineseTraditional: return "zht";
                case SystemLanguage.Czech: return "cs";
                case SystemLanguage.Danish: return "da";
                case SystemLanguage.Dutch: return "nl";
                case SystemLanguage.English: return "en";
                case SystemLanguage.Estonian: return "et";
                case SystemLanguage.Faroese: return "fo";
                case SystemLanguage.Finnish: return "fi";
                case SystemLanguage.French: return "fr";
                case SystemLanguage.German: return "de";
                case SystemLanguage.Greek: return "el";
                case SystemLanguage.Hebrew: return "he";
                case SystemLanguage.Icelandic: return "is";
                case SystemLanguage.Indonesian: return "id";
                case SystemLanguage.Japanese: return "jp";
                case SystemLanguage.Korean: return "kr";
                case SystemLanguage.Latvian: return "lv";
                case SystemLanguage.Lithuanian: return "lt";
                case SystemLanguage.Norwegian: return "no";
                case SystemLanguage.Polish: return "pl";
                case SystemLanguage.Portuguese: return "pt";
                case SystemLanguage.Romanian: return "ro";
                case SystemLanguage.Russian: return "ru";
                case SystemLanguage.SerboCroatian: return "hr";
                case SystemLanguage.Slovak: return "sk";
                case SystemLanguage.Slovenian: return "sl";
                case SystemLanguage.Spanish: return "es";
                case SystemLanguage.Swedish: return "sv";
                case SystemLanguage.Thai: return "th";
                case SystemLanguage.Turkish: return "tr";
                case SystemLanguage.Ukrainian: return "uk";
                case SystemLanguage.Vietnamese: return "vi";
                case SystemLanguage.Hungarian: return "hu";
                case SystemLanguage.Italian: return "it";
                case SystemLanguage.Unknown: return "en";
            }

            return "en";
        }

        // 过滤不支持的语言
        private string GetLocal(string language)
        {
            if (SupportedLocale.Contains(language))
                return language;

            return Locale.ENGLISH;
        }
        
        public string GetCurrentLocale()
        {
            return m_current_locale;
        }
        
        public TMP_FontAsset GetLocaleFont()
        {
#if UNITY_EDITOR
            if (!Application.isPlaying && m_current_locale != Locale.ENGLISH)
                return GetFont(Locale.ENGLISH);
#endif
            return GetFont(m_current_locale);
        }
        
        /// <summary>
        /// 获取字体
        /// </summary>
        /// <param name="language"></param>
        /// <returns></returns>
        public TMP_FontAsset GetFont(string language)
        {
            string locale = Util.FirstCharToUpper(language);
            string key = string.Format("LocaleFont_{0} SDF", locale);
            TMP_FontAsset fontAsset = null;
            if(!m_CacheFont.TryGetValue(key, out fontAsset))
            {
                string path = string.Format("Fonts/{0}/{1}", locale, key);
                fontAsset = Resources.Load<TMP_FontAsset>(path);
                m_CacheFont.Add(key, fontAsset);
            }
            return fontAsset;
        }
        
        /// <summary>
        /// 获取材质
        /// </summary>
        /// <param name="language"></param>
        /// <param name="suffix"></param>
        /// <returns></returns>
        /// todo:默认材质的加载路径，目前不对
        public Material GetMaterial(string language, string suffix)
        {
            string locale = Game.Framework.Utils.Util.FirstCharToUpper(language);
            string key = string.Format("LocaleFont_{0} SDF {1}", locale, suffix);
            Material mat = null;

            if (m_CacheMaterial.TryGetValue(key, out mat))
            {
                return mat;
            }
            else
            {
                string path = string.Format("Fonts/{0}/{1}", locale, key);
                mat = Resources.Load<Material>(path);
                m_CacheMaterial.Add(key, mat);
                return mat;
            }
        }

        // todo:默认材质的加载路径，目前不对
        public Material GetLocaleMaterial(string suffix)
        {
            
#if UNITY_EDITOR
            if (!Application.isPlaying && m_current_locale != Locale.ENGLISH)
                return GetMaterial(Locale.ENGLISH, suffix);
#endif
            return GetMaterial(m_current_locale, suffix);
        }
        
        public string GetLocalizedString(string key)
        {
            if(string.IsNullOrEmpty(key)) return null;
            
            string _key = key.Trim();

            if (String.IsNullOrEmpty(_key))
            {
                return String.Empty;
            }

            if (_key.StartsWith("&key", StringComparison.InvariantCulture))
            {
                _key = _key.Substring(5);
            }

            return LanguageConfigManager.Instance.GetLocalString(_key, m_current_locale);
        }
    }
}

